home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 12021 / 12021.xpi / components / autocomplete.js
Text File  |  2009-06-11  |  7KB  |  212 lines

  1. // Source: https://developer.mozilla.org/en/How_to_implement_custom_autocomplete_search_component
  2.  
  3. const Ci = Components.interfaces;
  4.  
  5. const CLASS_ID = Components.ID("6224daa1-71a2-4d1a-ad90-01ca1c08e323");
  6. const CLASS_NAME = "Simple AutoComplete";
  7. const CONTRACT_ID = "@mozilla.org/autocomplete/search;1?name=simple-autocomplete";
  8.  
  9. // Implements nsIAutoCompleteResult
  10. function SimpleAutoCompleteResult(searchString, searchResult,
  11.                                   defaultIndex, errorDescription,
  12.                                   results, comments) {
  13.   this._searchString = searchString;
  14.   this._searchResult = searchResult;
  15.   this._defaultIndex = defaultIndex;
  16.   this._errorDescription = errorDescription;
  17.   this._results = results;
  18.   this._comments = comments;
  19. }
  20.  
  21. SimpleAutoCompleteResult.prototype = {
  22.   _searchString: "",
  23.   _searchResult: 0,
  24.   _defaultIndex: 0,
  25.   _errorDescription: "",
  26.   _results: [],
  27.   _comments: [],
  28.  
  29.   /**
  30.    * The original search string
  31.    */
  32.   get searchString() {
  33.     return this._searchString;
  34.   },
  35.  
  36.   /**
  37.    * The result code of this result object, either:
  38.    *         RESULT_IGNORED   (invalid searchString)
  39.    *         RESULT_FAILURE   (failure)
  40.    *         RESULT_NOMATCH   (no matches found)
  41.    *         RESULT_SUCCESS   (matches found)
  42.    */
  43.   get searchResult() {
  44.     return this._searchResult;
  45.   },
  46.  
  47.   /**
  48.    * Index of the default item that should be entered if none is selected
  49.    */
  50.   get defaultIndex() {
  51.     return this._defaultIndex;
  52.   },
  53.  
  54.   /**
  55.    * A string describing the cause of a search failure
  56.    */
  57.   get errorDescription() {
  58.     return this._errorDescription;
  59.   },
  60.  
  61.   /**
  62.    * The number of matches
  63.    */
  64.   get matchCount() {
  65.     return this._results.length;
  66.   },
  67.  
  68.   /**
  69.    * Get the value of the result at the given index
  70.    */
  71.   getValueAt: function(index) {
  72.     return this._results[index];
  73.   },
  74.  
  75.   /**
  76.    * Get the comment of the result at the given index
  77.    */
  78.   getCommentAt: function(index) {
  79.     return this._comments[index];
  80.   },
  81.  
  82.   /**
  83.    * Get the style hint for the result at the given index
  84.    */
  85.   getStyleAt: function(index) {
  86.     if (!this._comments[index])
  87.       return null;  // not a category label, so no special styling
  88.  
  89.     if (index == 0)
  90.       return "suggestfirst";  // category label on first line of results
  91.  
  92.     return "suggesthint";   // category label on any other line of results
  93.   },
  94.  
  95.   /**
  96.    * Get the image for the result at the given index
  97.    * The return value is expected to be an URI to the image to display
  98.    */
  99.   getImageAt : function (index) {
  100.     return "";
  101.   },
  102.  
  103.   /**
  104.    * Remove the value at the given index from the autocomplete results.
  105.    * If removeFromDb is set to true, the value should be removed from
  106.    * persistent storage as well.
  107.    */
  108.   removeValueAt: function(index, removeFromDb) {
  109.     this._results.splice(index, 1);
  110.     this._comments.splice(index, 1);
  111.   },
  112.  
  113.   QueryInterface: function(aIID) {
  114.     if (!aIID.equals(Components.interfaces.nsIAutoCompleteResult) && !aIID.equals(Components.interfaces.nsISupports))
  115.         throw Components.results.NS_ERROR_NO_INTERFACE;
  116.     return this;
  117.   }
  118. };
  119.  
  120.  
  121. // Implements nsIAutoCompleteSearch
  122. function SimpleAutoCompleteSearch() {
  123. }
  124.  
  125. SimpleAutoCompleteSearch.prototype = {
  126.   /*
  127.    * Search for a given string and notify a listener (either synchronously
  128.    * or asynchronously) of the result
  129.    *
  130.    * @param searchString - The string to search for
  131.    * @param searchParam - An extra parameter
  132.    * @param previousResult - A previous result to use for faster searchinig
  133.    * @param listener - A listener to notify when the search is complete
  134.    */
  135.   startSearch: function(searchString, searchParam, result, listener) {
  136.     // This autocomplete source assumes the developer attached a JSON string
  137.     // to the the "autocompletesearchparam" attribute or "searchParam" property
  138.     // of the <textbox> element. The JSON is converted into an array and used
  139.     // as the source of match data. Any values that match the search string
  140.     // are moved into temporary arrays and passed to the AutoCompleteResult
  141.     if (searchParam.length > 0) {
  142.       var nativeJSON = Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON);
  143.       var searchResults = nativeJSON.decode(searchParam);
  144.       var results = [];
  145.       var comments = [];
  146.       for (i=0; i<searchResults.length; i++) {
  147.         if (searchResults[i].value.indexOf(searchString) == 0) {
  148.           results.push(searchResults[i].value);
  149.           if (searchResults[i].comment)
  150.             comments.push(searchResults[i].comment);
  151.           else
  152.             comments.push(null);
  153.         }
  154.       }
  155.       var newResult = new SimpleAutoCompleteResult(searchString, Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS, 0, "", results, comments);
  156.       listener.onSearchResult(this, newResult);
  157.     }
  158.   },
  159.  
  160.   /*
  161.    * Stop an asynchronous search that is in progress
  162.    */
  163.   stopSearch: function() {
  164.   },
  165.     
  166.   QueryInterface: function(aIID) {
  167.     if (!aIID.equals(Components.interfaces.nsIAutoCompleteSearch) && !aIID.equals(Components.interfaces.nsISupports))
  168.         throw Components.results.NS_ERROR_NO_INTERFACE;
  169.     return this;
  170.   }
  171. };
  172.  
  173. // Factory
  174. var SimpleAutoCompleteSearchFactory = {
  175.   singleton: null,
  176.   createInstance: function (aOuter, aIID) {
  177.     if (aOuter != null)
  178.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  179.     if (this.singleton == null)
  180.       this.singleton = new SimpleAutoCompleteSearch();
  181.     return this.singleton.QueryInterface(aIID);
  182.   }
  183. };
  184.  
  185. // Module
  186. var SimpleAutoCompleteSearchModule = {
  187.   registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) {
  188.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  189.     aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  190.   },
  191.  
  192.   unregisterSelf: function(aCompMgr, aLocation, aType) {
  193.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  194.     aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  195.   },
  196.   
  197.   getClassObject: function(aCompMgr, aCID, aIID) {
  198.     if (!aIID.equals(Components.interfaces.nsIFactory))
  199.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  200.  
  201.     if (aCID.equals(CLASS_ID))
  202.       return SimpleAutoCompleteSearchFactory;
  203.  
  204.     throw Components.results.NS_ERROR_NO_INTERFACE;
  205.   },
  206.  
  207.   canUnload: function(aCompMgr) { return true; }
  208. };
  209.  
  210. // Module initialization
  211. function NSGetModule(aCompMgr, aFileSpec) { return SimpleAutoCompleteSearchModule; }
  212.